"""
使用之前的 ToxiCN 数据重新测试 v4 模型
"""
import json
import requests
from tqdm import tqdm
from sklearn.metrics import accuracy_score, precision_recall_fscore_support

def retest_v4_model():
    print("=" * 70)
    print("🧪 ToxiCN 数据集 v4 模型测试")
    print("=" * 70)
    
    # 读取之前的测试数据
    with open('toxicn_test_results.json', 'r', encoding='utf-8') as f:
        old_results = json.load(f)
    
    samples = old_results['details']
    print(f"\n使用本地数据: {len(samples)} 条")
    print(f"数据来源: toxicn_test_results.json\n")
    
    # 测试 v4 模型
    api_url = "http://localhost:8000/api/validate"
    results = {
        'total': 0,
        'correct': 0,
        'wrong': 0,
        'details': []
    }
    
    print("🧪 开始测试 v4 模型...\n")
    
    for sample in tqdm(samples, desc="测试进度"):
        results['total'] += 1
        
        try:
            response = requests.post(
                api_url,
                json={"text": sample['content']},
                timeout=30
            )
            
            if response.status_code == 200:
                result = response.json()
                
                expected_safe = (sample['expected'] == 'safe')
                actual_safe = result['is_safe']
                is_correct = (expected_safe == actual_safe)
                
                if is_correct:
                    results['correct'] += 1
                else:
                    results['wrong'] += 1
                
                results['details'].append({
                    'content': sample['content'],
                    'topic': sample['topic'],
                    'expected': sample['expected'],
                    'actual': 'safe' if actual_safe else 'toxic',
                    'correct': is_correct,
                    'confidence': result.get('confidence', 0)
                })
        except Exception as e:
            print(f"\n❌ 请求失败: {str(e)}")
    
    # 计算指标
    print("\n" + "=" * 70)
    print("📊 v4 模型测试结果")
    print("=" * 70)
    
    total = results['total']
    correct = results['correct']
    accuracy = correct / total if total > 0 else 0
    
    # True Positive, False Positive, False Negative
    tp = sum(1 for d in results['details'] 
             if d['expected'] == 'toxic' and d['actual'] == 'toxic')
    fp = sum(1 for d in results['details'] 
             if d['expected'] == 'safe' and d['actual'] == 'toxic')
    fn = sum(1 for d in results['details'] 
             if d['expected'] == 'toxic' and d['actual'] == 'safe')
    
    precision = tp / (tp + fp) if (tp + fp) > 0 else 0
    recall = tp / (tp + fn) if (tp + fn) > 0 else 0
    f1 = 2 * precision * recall / (precision + recall) if (precision + recall) > 0 else 0
    
    print(f"\n总测试数: {total}")
    print(f"✅ 正确: {correct} ({accuracy*100:.2f}%)")
    print(f"❌ 错误: {results['wrong']} ({results['wrong']/total*100:.2f}%)")
    
    print(f"\n性能指标:")
    print(f"  Accuracy (准确率): {accuracy:.4f}")
    print(f"  Precision (精确率): {precision:.4f}")
    print(f"  Recall (召回率): {recall:.4f}")
    print(f"  F1-Score: {f1:.4f}")
    
    # 对比之前的结果
    print(f"\n" + "=" * 70)
    print("📈 v4 vs v2 对比")
    print("=" * 70)
    
    # 从旧结果计算 v2 指标
    old_details = old_results['details']
    old_tp = sum(1 for d in old_details if d['expected'] == 'toxic' and d['actual'] == 'toxic')
    old_fp = sum(1 for d in old_details if d['expected'] == 'safe' and d['actual'] == 'toxic')
    old_fn = sum(1 for d in old_details if d['expected'] == 'toxic' and d['actual'] == 'safe')
    
    old_precision = old_tp / (old_tp + old_fp) if (old_tp + old_fp) > 0 else 0
    old_recall = old_tp / (old_tp + old_fn) if (old_tp + old_fn) > 0 else 0
    old_f1 = 2 * old_precision * old_recall / (old_precision + old_recall) if (old_precision + old_recall) > 0 else 0
    old_accuracy = old_results['correct'] / old_results['total']
    
    print(f"\nv2 模型 (BERT base):")
    print(f"  Accuracy: {old_accuracy:.4f}")
    print(f"  Precision: {old_precision:.4f}")
    print(f"  Recall: {old_recall:.4f}")
    print(f"  F1-Score: {old_f1:.4f}")
    
    print(f"\nv4 模型 (RoBERTa Large):")
    print(f"  Accuracy: {accuracy:.4f} ({(accuracy-old_accuracy)*100:+.2f}%)")
    print(f"  Precision: {precision:.4f} ({(precision-old_precision)*100:+.2f}%)")
    print(f"  Recall: {recall:.4f} ({(recall-old_recall)*100:+.2f}%)")
    print(f"  F1-Score: {f1:.4f} ({(f1-old_f1)*100:+.2f}%)")
    
    # 统计改进的样本
    improvements = 0
    for i, (old, new) in enumerate(zip(old_details, results['details'])):
        if not old['correct'] and new['correct']:
            improvements += 1
    
    print(f"\n✅ v4 修复了 {improvements} 个 v2 错误样本")
    
    # 保存结果
    with open('toxicn_v4_results.json', 'w', encoding='utf-8') as f:
        json.dump(results, f, indent=2, ensure_ascii=False)
    
    print(f"\n💾 v4 测试结果已保存到: toxicn_v4_results.json")

if __name__ == "__main__":
    retest_v4_model()
